#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
typedef long long LL;
// 这里的关键是如何让中间插入和删除变得更加高效
// 刚好符合链表的特性
struct node
{
    LL _sum;
    int _index;
    bool operator>(const node &a) const
    {
        return _sum == a._sum ? _index > a._index : _sum > a._sum;
    }
};

const int N = 500010;
LL e[N];
int ne[N], pre[N], idx = 0, head = -1, tail = -1;
bool st[N];
priority_queue<node, vector<node>, greater<node>> q;

int main()
{
    int n, k;
    cin >> n >> k;
    // 将所有数用链表存储起来
    for (int i = 0; i < n; ++i)
    {
        int tmp;
        cin >> tmp;
        e[idx] = tmp;
        if (head == -1)
        {
            ne[idx] = head;
            pre[idx] = head;
            head = idx;
            tail = idx;
        }
        else
        {
            ne[idx] = ne[tail];
            pre[idx] = tail;

            ne[tail] = idx;
            tail = idx;
        }
        q.push({tmp, idx});
        idx++;
    }
    while (k)
    {
        const auto &nd = q.top();
        LL t = nd._sum;
        int index = nd._index;
        q.pop();

        if (e[index] != t || st[index])
            continue;
        --k;
        st[index] = true;
        if (index != head)
        {
            e[pre[index]] += t;
            q.push({e[pre[index]], pre[index]});
        }
        if (index != tail)
        {
            e[ne[index]] += t;
            q.push({e[ne[index]], ne[index]});
        }

        if (index == tail)
        {
            tail = pre[tail];
            ne[pre[index]] = -1;
        }
        else if (index == head)
        {
            head = ne[head];
            pre[ne[index]] = -1;
        }
        else
        {
            ne[pre[index]] = ne[index];
            pre[ne[index]] = pre[index];
        }
    }
    for (int i = head; ~i; i = ne[i])
        cout << e[i] << ' ';
    cout << endl;
    return 0;
}